package schoolsource.model;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import java.util.logging.Level;

import schoolsource.sql.DBSQLAccessor;
import schoolsource.util.SchoolLogger;

/**
 *
 * @author Steven Steele
 * Copyright 2003
 *
 * Item containing a date value, database tools for saving and loading it, its required-ness,
 * and validation tools.
 */
public class DateNoTimeItem extends Item {

	// The value stored by the Item
	private GregorianCalendar value;
	// The date format required of strings by the DBSQLAccessor translator method.
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	// The date format required to translate from the DBSQLAccessor translator method to a date.
	private SimpleDateFormat sdfNoTime = new SimpleDateFormat("yyyy-MM-dd");
	// The date format required of string to set the value of the Item
	private SimpleDateFormat sdfMMDDYYYY = new SimpleDateFormat("MM/dd/yyyy");

	/**
	 * Returns a new Item with the database field name, value, and required-ness set
	 * to the parameter values.
	 * @param newField The name of the database field where the date value is stored.
	 * @param newVal The value of the date.
	 * @param newReq Whether the date value may be unset. True indicates it may not be unset.
	 */
	public DateNoTimeItem(String newField, String newVal, boolean newReq) {
		setFieldName(newField);
		setValue(newVal);
		setRequired(newReq);
	}

	/**
	 * Returns a new Item with the database field name, value, and required-ness set
	 * to the parameter values.
	 * @param newField The name of the database field where the date value is stored.
	 * @param newVal The value of the date.
	 * @param newReq Whether the date value may be unset. True indicates it may not be unset.
	 */
	public DateNoTimeItem(String newField, GregorianCalendar newVal, boolean newReq) {
		setFieldName(newField);
		setTrueValue(newVal);
		setRequired(newReq);
	}

	/**
	 * Sets the value using a string. The date must be in the format "MM/DD/YYYY".
	 * @param newValue The value to set the date.
	 */
	public void setValue(String newValue) {
		System.err.println("set value to : "+newValue);
		try {
			if (value == null) {
				value = new GregorianCalendar();
			}
			value.setTime(sdfMMDDYYYY.parse(newValue, new ParsePosition(0)));
		} catch (NullPointerException npe) {
			System.err.println("null pointer");
			value = null;
		}
		validate();
	}

	/**
	 * Sets the value using a Date object.
	 * @param newTrueValue An object that can be cast to a Date.
	 */
	public void setTrueValue(Object newTrueValue) {
		value = (GregorianCalendar) newTrueValue;
		validate();
	}

	/**
	 * Returns the string representation of the Item.
	 * @return The string representation of the Item.
	 */
	public String toString() {
		String returnString = "";
		if (value != null) {
			returnString = sdfMMDDYYYY.format(value.getTime());
			//        returnString = sdfNoTime.format(value.getTime());
		}
		return returnString;
	}

	/**
	 * Returns the object associated with the Item.
	 * @return The object associated with the Item.
	 */
	public Object getObject() {
		return value;
	}

	/**
	 * Returns a string formatted in the appropriate manner for the Item,
	 * according to the DBSQLAccessor passed in.
	 * @param dba A DBSQLAccessor that defines how values are represented in the
	 * target database.
	 */
	public String getDBFormattedString(DBSQLAccessor dba) {
		String returnString = "";
		if (value != null) {
			returnString = sdf.format(value.getTime());
//			SchoolLogger.logger.log(
//				Level.INFO,
//				"returnString: " + returnString);
			//		returnString = sdfNoTime.format(value.getTime());
		}
		SchoolLogger.logger.log(
			Level.INFO,
			"dba.getDBFormattedDate: " + dba.getDBFormattedDate(returnString));
		return dba.getDBFormattedDate(returnString);
	}

	/**
	 * Sets the value of the Item according to the interpretation of a database representation
	 * of the Item using the passed-in DBSQLAccessor to interpret it.
	 * @param dbString The database representation of the Item.
	 * @param dba The DBSQLAccessor that defines how values are translated from the database
	 * representation to the Item value.
	 */
	public void createFromDBString(String dbString, DBSQLAccessor dba) {
		System.err.println(" dbstring: "+dbString);
		try {
			if (value == null) {
				value = new GregorianCalendar();
			}
			value.setTime(
				sdfNoTime.parse(
					dba.removeDBTagsFromDate(dbString),
					new ParsePosition(0)));
		} catch (NullPointerException npe) {
			System.err.println("null point in create db string");
			value = null;
		}
		System.err.println("value time: "+this.toString());
		validate();
	}

	/**
	 * Indicates whether the Item is valid. This value is current only after the Item
	 * has validate() called on it.
	 * @return A boolean indicating whether the Item is valid.
	 */
	public boolean isValid() {
		return valid;
	}

	/**
	 * Processes the Item and determines whether it is valid strictly according to rules
	 * governing the Item implementation and whether the Item is required.
	 */
	public void validate() {
		if (isRequired() && getObject() == null) {
			setErrorString("This field is required and must be in the format of mm/dd/yyyy.");
			setValid(false);
		} else {
			setValid(true);
		}
	}
}